One of the side effects of adding mod support into the game engine is that we had to build a cross-platform dynamic/shared library loader. This is enabled by the UntitledRuntimeLibraryLoader which we developed. To include it use:
#include <urll/urll.h>
All the functions under the URLL
namespace named and
work like in Unix, so they can feel familiar to use. There are also 2
utility functions for ease of use.
Functions
dlopen
- returns avoid*
handle given a path to the library*dlerror
- returns achar*
with the latest errordlclose
- closes the library given the handle**dlsym
- retrieves a symbol from the library given a name
* Due to Windows restrictions dlopen
cannot receive a
flag and will always default to lazy loading
** dlclose
closes the library handle, which makes all
the memory acquired from dlsym
null
dlsym
There are currently 3 definitions of dlsym
, all of them
take a handle and a name
- Standard
dlsym
that returns avoid*
and only takes a handle and a name std::function
variant that assigns thevoid*
fromdlsym
to anstd::function
- The templated variant, which casts the
void*
to the specified template type
Here are some examples:
dlsym
with std::function
std::function<void(void)> func;
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
return -1;
}
(); func
dlsym
with a templated type
void(*func)(void);
// We check against nullptr or the handle for errors
if (URLL::dlsym(handle, "func", func) == nullptr)
{
return -1;
}
(); func
regular dlsym
int* a = (int*)URLL::dlsym(handle, "func", func);
// We check against nullptr or the handle for errors
if (a == nullptr)
{
return -1;
}
std::cout << *a << std::endl;
Example of full URLL usage
This is an extract from the auto-generated main file for the modded executable
#ifdef _WIN32
void* handle = URLL::dlopen("Modlib.dll");
#else
// That https://madladsquad.com/ is required on unix systems
void* handle = URLL::dlopen("https://madladsquad.com/libModlib.so");
#endif
bool bCanClose = false;
if (handle != nullptr)
{
= true;
bCanClose if (URLL::dlsym(handle, "modlibbegin", UVK::global.modbegin) == handle && URLL::dlsym(handle, "modlibend", UVK::global.modend) == handle && URLL::dlsym(handle, "modlibtick", UVK::global.modtick) == handle)
.consoleLog("Loaded all mods!", UVK_LOG_TYPE_SUCCESS);
loggerelse
.consoleLog("Failed to load some or all of the initial mod library functions, mod events will not be loaded! Error: ", UVK_LOG_TYPE_WARNING, URLL::dlerror());
logger}
else
.consoleLog("Failed to load the mod library!", UVK_LOG_TYPE_WARNING);
logger
...
(handle); dlclose
- Home
- Beginner concepts
- Advanced concepts
- Engine developer and contributor resources